#pragma once

#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include <cstring>
#include <cerrno>
#include <string>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <mutex>

#include "yj_return.hpp"

class i2c_v1
{
private:
    int _fd = -1;
    uint8_t _device_address;
    std::string _dev_path;

    std::mutex _i2c_mutex;

    yj_return _flag;

public:
    // 构造函数：返回错误码代替异常
    i2c_v1(const std::string dev_path, uint8_t device_address);
    // dev_path = "/dev/i2c-1"
    yj_return open();
    void close();
    ~i2c_v1();
    
        // 禁止拷贝,因为锁不可拷贝
    i2c_v1(const i2c_v1 &) = delete;            // 禁止拷贝构造函数
    i2c_v1 &operator=(const i2c_v1 &) = delete; // 禁止拷贝赋值运算符

    // 设置地址（返回错误码）
    yj_return set_address(uint8_t address);

    // 写寄存器（返回布尔值）
    yj_return write_register(uint8_t reg, const uint8_t *data, uint16_t len);

    // 读寄存器（返回布尔值）
    yj_return read_register(uint8_t reg, uint8_t *data, uint16_t len);

    uint8_t get_address();
    std::string get_dev_path();
    yj_return get_flag();
    yj_return is_open();
    void print_config();
};